<script setup>
import http from "./utils/http";
import { ref, watch, onMounted, reactive } from "vue";
import { ElMessage } from "element-plus";

const res = ref("等待发送请求");
const callMess = ref("等待发送请求");
const deviceMess = ref("等待发送请求");
const callAddressMess = ref("等待发送请求");
const callIdPath = ref("");
const callIdSecondPath = ref("");
const devicePath = ref("");
const input = ref("");
const callIntervalid = ref(0);
const orderCallCancelIntervalid = ref(0);
const deviceIntervalid = ref(0);
const seatCode = ref("");
const callPhoneNumber = ref("");
const deviceId = ref("");
const initiateTransferNumber = ref("");
const callState = ref("");
const isTransferDone = ref(true);
const telFlag = ref(true);
const inviteNumber = ref("");
const inviteNumber2 = ref("");
const intervalIds = [];
const isInviteDone = ref(true);
const callIntervalSecondId = ref(0);

onMounted(() => {
  seatCode.value = sessionStorage.getItem("seatCode") || "";
});

watch(callIdPath, (newV, oldV) => {
  if (newV) {
    orderCallDetail();
  } else {
    cancelOrderCallDetail();
  }
});

watch(callIdSecondPath, (newV, oldV) => {
  if (newV) {
    orderCallDetail(newV, true);
  } else {
    cancelOrderCallDetail(true);
  }
});

watch(callState, (newV, oldV) => {
  if (newV === "Ringing") {
    ElMessage.success("来电话了");
  } else if (newV === "Dialing") {
    ElMessage.success("外呼中");
  } else if (newV === "Established") {
    ElMessage.success("通话中");
    if (callIdSecondPath.value) {
      isTransferDone.value = false;
      isInviteDone.value = false;
    }
  }
});

const testXhr = () => {
  var xhr = new XMLHttpRequest();

  // 配置请求参数
  xhr.open("POST", "https://sh-gws.csvw.com:8090/api/v2/notifications");

  // 设置请求头信息
  xhr.setRequestHeader("Content-Type", "application/json");
  xhr.setRequestHeader("Authorization", "Basic NzE1MTY2Og==");

  // 注册回调函数
  xhr.onreadystatechange = function () {
    if (xhr.readyState === XMLHttpRequest.DONE) {
      if (xhr.status === 200) {
        console.log("请求成功，服务器返回的数据是：" + xhr.responseText);
      } else {
        console.log("请求失败，错误码：" + xhr.status);
      }
    }
  };

  // 发送请求（POST方式）
  var data = [
    {
      id: "35",
      channel: "/meta/connect",
      connectionType: "long-polling",
      advice: { timeout: 0 },
      clientId: "or1lc3mbupn3l76mxtvvu4q9p9y",
    },
  ];
  xhr.send(JSON.stringify(data));
};

const reset = () => {
  res.value = "等待发送请求";
  callMess.value = "等待发送请求";
  deviceMess.value = "等待发送请求";
  callAddressMess.value = "等待发送请求";
  callIdPath.value = "";
  callIdSecondPath.value = "";
  devicePath.value = "";
  input.value = "";
  callIntervalid.value = 0;
  callIntervalSecondId.value = 0;
  orderCallCancelIntervalid.value = 0;
  deviceIntervalid.value = 0;
  telFlag.value = true;
  isTransferDone.value = true;
  isInviteDone.value = true;
  seatCode.value = "";
  callPhoneNumber.value = "";
  deviceId.value = "";
  initiateTransferNumber.value = "";
  callState.value = "";
  inviteNumber.value = "";
  inviteNumber2.value = "";
  intervalIds.length > 0 && intervalIds.forEach((i) => clearInterval(i));
};

const handleClick = async () => {
  // res.value = "...";
  // let url = "/cc/api/v2/diagnostics/version";
  // const data = await http.get(url);
  // res.value = data.data;
  const RollFreeApi = {
    appId: "himlswmfn3vedevz",
    appSecret: "VWlRUEZOOHBrRXVRZWNDdHhNZGg0UT09",
  };
  fetch("https://sh-gws.csvw.com:8090/api/v2/diagnostics/version", {})
    .then((response) => response.json())
    .then((data) => console.log(data));

  // const data = await http.get("/aa/api/v2/diagnostics/version");

  // const res = await fetch(
  //   "https://sh-gws.csvw.com/api/v2/diagnostics/version",
  //   {
  //     method: "Get",
  //     headers: {
  //       "Content-Type": "application/json",
  //       Authorization: "Basic " + window.btoa("61101" + ":" + ""),
  //     },
  //     keepalive: true,
  //   }
  // );

  // console.log(data);
};

const getUserInfo = async () => {
  res.value = "...";
  let url = "/cc/api/v2/me";
  const data = await http.get(url);
  res.value = data.data;
};

const getDevices = async () => {
  res.value = "...";
  let url = "/cc/api/v2/me/devices?fields=*";
  const data = await http.get(url);
  deviceId.value = data.data.devices[0].id || "";
  res.value = data.data;
};

const ready = async () => {
  res.value = "...";
  let url = "/cc/api/v2/me/channels/voice";
  const data = await http.post(url, { operationName: "Ready" });
  res.value = data.data;
};

const startContactCenterSession = async () => {
  res.value = "...";
  if (!input.value) return ElMessage.error("请输入分机号");
  if (!seatCode.value) return ElMessage.error("请输入坐席号");
  let url = "/cc/api/v2/me";
  let p = {
    operationName: "StartContactCenterSession",
    place: input.value,
    loginCode: seatCode.value,
    channels: ["voice"],
  };
  const data = await http.post(url, p);
  res.value = data.data;
};

const orderDevice = async () => {
  deviceMess.value = "...";
  let url = "/cc/api/v2/me/devices";
  const data = await http.get(url);
  deviceMess.value = data.data;
  devicePath.value = data.data.paths[0] || "";
};
const orderCallCancel = () => {
  clearInterval(orderCallCancelIntervalid.value);
};
const orderCall = async () => {
  callAddressMess.value = "...";
  let url = "/cc/api/v2/me/calls";
  orderCallCancelIntervalid.value = setInterval(async () => {
    const data = await http.get(url);
    callAddressMess.value = data.data;
    callIdPath.value = data.data.paths[0].substr(7, 99) || "";
    callIdSecondPath.value = data.data.paths[1] || "";
  }, 1500);
  intervalIds.push(orderCallCancelIntervalid.value);
};

const endContactCenterSession = async () => {
  res.value = "...";
  let url = "/cc/api/v2/me";
  const data = await http.post(url, {
    operationName: "EndContactCenterSession",
  });
  res.value = data.data;
};
const notReady = async () => {
  res.value = "...";
  let url = "/cc/api/v2/me/channels/voice";
  const data = await http.post(url, { operationName: "NotReady" });
  res.value = data.data;
};
const answer = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, { operationName: "Answer" });
  res.value = data.data;
};
const call = async () => {
  res.value = "...";
  if (!callPhoneNumber.value) return ElMessage.error("电话为空");
  if (!deviceId.value) return ElMessage.error("设备ID为空");
  let url = `/cc/api/v2/me/devices/${deviceId.value}/calls`;
  const data = await http.post(url, {
    operationName: "Dial",
    destination: {
      phoneNumber: callPhoneNumber.value,
    },
  });
  res.value = data.data;
  telFlag.value = false;
};
const hold = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  let p = {
    operationName: "Hold",
    // extensions: "music/silence/silence.wav",
  };
  const data = await http.post(url, { operationName: "Hold" });
  res.value = data.data;
};
const retrieve = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, { operationName: "Retrieve" });
  res.value = data.data;
};
const hangUp = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, { operationName: "Hangup" });
  res.value = data.data;
};
const reject = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, { operationName: "Reject" });
  res.value = data.data;
};

const muteCall = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, { operationName: "MuteCall" });
  res.value = data.data;
};

const unMuteCall = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, { operationName: "UnmuteCall" });
  res.value = data.data;
};

const startCallRecording = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, { operationName: "StartCallRecording" });
  res.value = data.data;
};

const pauseCallRecording = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, { operationName: "PauseCallRecording" });
  res.value = data.data;
};
const resumeCallRecording = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, { operationName: "ResumeCallRecording" });
  res.value = data.data;
};

const orderCallDetail = async (
  callPath = callIdPath.value,
  isSecond = false
) => {
  callMess.value = "...";
  if (!callPath) return ElMessage.error("通话路径为空");
  let url = "/cc/api/v2/me" + callPath;
  let id = setInterval(async () => {
    const data = await http.get(url);
    callMess.value = data.data;
    callState.value = data.data.call.state || "";
  }, 3000);
  if (isSecond) {
    callIntervalSecondId.value = id;
  } else {
    callIntervalid.value = id;
  }
  intervalIds.push(callIntervalid.value);
};

const orderDeviceDetail = async () => {
  deviceMess.value = "...";
  if (!devicePath.value) return ElMessage.error("设备路径为空");
  let url = "/cc/api/v2/me" + devicePath.value;
  deviceIntervalid.value = setInterval(async () => {
    const data = await http.get(url);
    deviceMess.value = data.data;
  }, 3000);
  intervalIds.push(deviceIntervalid.value);
};
const cancelOrderCallDetail = (isSecond = false) => {
  clearInterval(isSecond ? callIntervalSecondId.value : callIntervalid.value);
};
const cancelOrderDeviceDetail = () => {
  clearInterval(deviceIntervalid.value);
};
const stopCallRecording = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, { operationName: "StopCallRecording" });
  res.value = data.data;
};
const singleStepConference = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  if (!inviteNumber.value) return ElMessage.error("邀请电话为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, {
    operationName: "SingleStepConference",
    destination: {
      phoneNumber: inviteNumber.value,
    },
  });
  res.value = data.data;
};
const initiateConference = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  if (!inviteNumber2.value) return ElMessage.error("邀请电话为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, {
    operationName: "InitiateConference",
    destination: {
      phoneNumber: inviteNumber2.value,
    },
  });
  res.value = data.data;
};
const initiateConferenceDone = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, {
    operationName: "CompleteConference",
  });
  res.value = data.data;
};
const singleStepTransfer = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, {
    operationName: "SingleStepTransfer",
    destination: {
      phoneNumber: "11006",
    },
  });
  res.value = data.data;
};
const setSeat = () => {
  sessionStorage.setItem("seatCode", seatCode.value);
};

const initiateTransfer = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  if (!initiateTransferNumber.value) return ElMessage.error("转接号码为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, {
    operationName: "InitiateTransfer",
    destination: {
      phoneNumber: initiateTransferNumber.value,
    },
  });
  res.value = data.data;
};

const initiateTransferDone = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, {
    operationName: "CompleteTransfer",
  });
  res.value = data.data;
};

const cancelSingleStepConference = () => {
  retrieve();
};

// TODO:此处的callID可能是另外一个
const initiateTransferCancel = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, {
    operationName: "Retrieve",
  });
  res.value = data.data;
};

const copy = () => {
  navigator.clipboard.writeText(JSON.stringify(callMess.value));
};
const callBackWork = async () => {};

const attachUserData = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, {
    operationName: "AttachUserData",
    userData: {
      ssjTest: "ssj-test-123",
    },
  });
  res.value = data.data;
};
const updateUserData = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, {
    operationName: "UpdateUserData",
    userData: {
      ssjTest: "ssj-test-2333333333",
    },
  });
  res.value = data.data;
};
const deleteUserData = async () => {
  alert("暂时用不到");
};
const deleteUserDataPair = async () => {
  res.value = "...";
  if (!callIdPath.value) return ElMessage.error("callID为空");
  let url = "/cc/api/v2/me" + callIdPath.value;
  const data = await http.post(url, {
    operationName: "DeleteUserDataPair",
    key: "ssjTest",
  });
  res.value = data.data;
};

const arrayReactive = reactive([]);

const arrayReactiveGetterWatch = watch(
  () => [...arrayReactive],
  (newValue, oldValue) => {
    console.log(
      "newArrayReactiveFuncWatch",
      newValue,
      "oldArrayReactiveFuncWatch",
      oldValue
    );

    let newLength = newValue.length;
    let oldLength = oldValue.length;
  }
);
const stopWatch = () => {
  arrayReactiveGetterWatch();
};
const shift = () => {
  arrayReactive.shift();
};
const cycle = () => {
  let id = setInterval(() => {}, 5000);
  arrayReactive.push({
    id,
  });
};
</script>

<template>
  <div class="">
    {{ arrayReactive }}<el-button @click="stopWatch"> 停止</el-button
    ><el-button @click="shift">删除</el-button>
    <el-button @click="cycle">循环</el-button>
    <el-button @click="testXhr">测试Xhr</el-button>
  </div>
  <div class="container">
    <div>
      <h4>----------------------------问题----------------------------</h4>
      <div>
        【留意】❓留意下关键状态枚举+ 默认请选择，外呼电话考虑前缀0或9类似情况
      </div>
      <div>【留意】没有查询所有坐席状态api</div>
      <div>【留意】非会议模式不支持mute</div>
    </div>

    <div>
      <h4>----------------------------笔记----------------------------</h4>
      <div>1、不用令牌也能直接访问，只需要头部有Authorization</div>
      <div>
        2、启动联系人中心会话时，软电话登录好，place写分机号，坐席就绪，就能打电话了（前提是需要配置好坐席和分机号的从属关系）
      </div>
      <div>3、从设备通知里面获取设备ID</div>
      <div>4、同步坐席状态给自己的后端</div>
      <div>5、转满意度：SingleStepTransfer</div>
      <div>
        6、通话状态：Dialing（外呼中），Established（接通），Ringing（响铃中），Held（保持）
      </div>
      <div>7、非会议模式不支持mute</div>
      <div>
        8、坐席A电话客户，后转接坐席B，B第一次通话ID是A和B之间的，callType是Consult，有parentCallPath，第二次在A完成转接的时候，通话ID变为A和客户的通话ID
      </div>
      <div>9、genesys给的随录数据是呼入有的</div>
    </div>

    <div>
      <h4>----------------------------请求----------------------------</h4>
      <div class="flex">
        <span>坐席号：</span>
        <el-input
          v-model="seatCode"
          placeholder="请输入坐席号"
          @change="setSeat"
        />
      </div>
      <div class="flex">
        <span>分机号：</span>
        <el-input v-model="input" placeholder="请输入分机号" />
      </div>
      <div style="margin-top: 16px">当前通话状态：{{ callState }}</div>
      <el-button type="warning" @click="reset">清空所有状态</el-button>
      <hr />
      <div>
        <el-button @click="handleClick">发送版本请求</el-button>
        <el-button @click="getUserInfo">获取用户信息</el-button>
        <el-button @click="getDevices">获取该用户设备及绑定用户状态</el-button>
        <!-- <el-button @click="bindDevice">绑定分机号设备</el-button> -->
      </div>
      <hr />
      <div>
        <el-button @click="orderCall" type="primary"
          >轮询获取订阅通知（call）的地址</el-button
        >
        <el-button @click="orderCallCancel" type="danger"
          >取消轮询获取订阅通知（call）的地址</el-button
        >
      </div>
      <div>
        <el-button @click="orderCallDetail" type="primary"
          >轮询获取（call）通知</el-button
        >
        <el-button @click="cancelOrderCallDetail" type="danger"
          >取消轮询获取（call）</el-button
        >
      </div>
      <div>
        <el-button @click="orderDevice" type="info"
          >获取订阅通知（device）的地址</el-button
        >
        <el-button @click="orderDeviceDetail" type="primary"
          >轮询获取（device）通知</el-button
        >
        <el-button @click="cancelOrderDeviceDetail" type="danger"
          >取消轮询获取（device）</el-button
        >
      </div>
      <hr />
      <div>
        <el-button @click="startContactCenterSession" type="success"
          >签入/启动联系人中心会话</el-button
        >
        <el-button @click="endContactCenterSession" type="danger"
          >签出/结束联系人中心会话</el-button
        >
        <el-button @click="ready" type="success">示闲/就绪</el-button>
        <el-button @click="notReady" type="danger">示忙/未就绪</el-button>
      </div>
      <div>
        <el-button @click="answer" type="success">接听电话</el-button>
        <el-button @click="reject" type="danger">拒接电话</el-button>
      </div>
      <div>
        <el-input v-model="callPhoneNumber" placeholder="请输入要拨打的号码" />
        <el-button @click="call" type="success">拨打电话</el-button>
        <el-button @click="hangUp" type="danger">挂断电话</el-button>
      </div>
      <hr />
      <div>
        <el-input
          v-model="initiateTransferNumber"
          placeholder="请输入要转接的号码"
        />
        <el-button @click="initiateTransfer" type="primary">转接电话</el-button>
        <el-button
          @click="initiateTransferDone"
          type="primary"
          :disabled="isTransferDone"
          >完成转接</el-button
        >
        <el-button @click="initiateTransferCancel" type="danger"
          >取消转接</el-button
        >
      </div>
      <div>
        <el-button @click="hold">保持电话</el-button>
        <el-button @click="retrieve">取消保持</el-button>
      </div>
      <div>
        <el-button @click="muteCall">静音</el-button>
        <el-button @click="unMuteCall">取消静音</el-button>
      </div>
      <div>
        方式一：（一步会议）
        <el-input v-model="inviteNumber" placeholder="请输入邀请电话" />
        <el-button @click="singleStepConference" type="primary"
          >邀请介入电话</el-button
        >
        <el-button @click="cancelSingleStepConference" type="danger"
          >取消邀请</el-button
        >
      </div>
      <div>
        方式二：（二步会议）
        <el-input v-model="inviteNumber2" placeholder="请输入邀请电话" />
        <el-button @click="initiateConference" type="primary"
          >邀请介入电话</el-button
        >
        <el-button
          @click="initiateConferenceDone"
          type="primary"
          :disabled="isInviteDone"
          >完成邀请</el-button
        >
        <el-button @click="cancelSingleStepConference" type="danger"
          >取消邀请</el-button
        >
      </div>
      <div>
        <el-button @click="singleStepTransfer">转满意度</el-button>
        <el-button @click="callBackWork">话后处理</el-button>
      </div>
      <div>
        <el-button @click="startCallRecording">开始录音</el-button>
        <el-button @click="pauseCallRecording">暂停录音</el-button>
        <el-button @click="resumeCallRecording">恢复录音</el-button>
        <el-button @click="stopCallRecording">结束录音</el-button>
      </div>
      <hr />
      <div>
        <el-button @click="attachUserData">添加随录数据</el-button>
        <el-button @click="updateUserData">更新随录数据</el-button>
        <el-button @click="deleteUserData">删除所有随录数据</el-button>
        <el-button @click="deleteUserDataPair">删除指定的随录数据key</el-button>
      </div>
    </div>

    <div class="display">
      <h4>----------------------------出参----------------------------</h4>
      <div class="display_content">
        <div class="res">
          <span>普通消息：</span>
          <div>{{ res }}</div>
        </div>
        <div class="res">
          <span>订阅Call地址消息：</span>
          <div>{{ callAddressMess }}</div>
        </div>
        <div class="res">
          <span
            >订阅Call状态消息：<el-link @click="copy" type="primary"
              >复制</el-link
            ></span
          >
          <div>{{ callMess }}</div>
        </div>
        <div class="res">
          <span>订阅Device状态消息：</span>
          <div>{{ deviceMess }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.container {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.flex {
  display: flex;
  align-items: center;
}
.display {
  width: 100%;
}
.display_content {
  display: grid;
  grid-template-rows: 1fr 1fr 1fr 1fr;
  row-gap: 16px;
}
.res {
  height: fit-content;
  padding: 16px;
  background-color: #eee;
}
.res span {
  display: block;
  font-weight: bold;
  margin-bottom: 16px;
}
.el-button {
  margin-top: 16px;
}
.el-input {
  width: 150px;
  margin-top: 16px;
  margin-right: 16px;
}
</style>
